package com.lvmama.task.job.worker;

import com.lvmama.task.common.service.TaskService;
import com.lvmama.task.common.utils.RandomCodeUtil;
import com.lvmama.task.common.utils.TaskUtil;
import com.lvmama.task.common.vo.Task;
import com.lvmama.task.job.common.TaskJobParameters;
import com.lvmama.task.job.thread.TaskThreadPoolFactory;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by IntelliJ IDEA.<p/>
 * User: troy-kou<p/>
 * Date: 14-1-6<p/>
 * Time: 下午3:59<p/>
 * Email:kouhongyu@163.com<p/>
 */
@Service
public class TaskGuardJob {

    Log log = LogFactory.getLog(TaskGuardJob.class);
    private TaskService taskService;

    public void execute() {

        //清理死线程
        cleanDieThread();
        //计算下次执行时间
        resetNextRunTime();
    }

    private void cleanDieThread() {
        Map<String, Object> paramMap = new HashMap<String, Object>();

        /**
         * 运行状态为“运行”
         */
        paramMap.put("status", Task.TASK_STATUS.RUN.getCode());
        paramMap.put("jobNode", TaskJobParameters.TASK_JOB_NODE);
        paramMap.put("owner", TaskJobParameters.TASK_JOB_OWNER);
        paramMap.put("_startRow", 1);
        paramMap.put("_endRow", 10000);

        List<Task> taskList = taskService.getTaskList(paramMap);

        for (Task task : taskList) {
            try {
                String sign = RandomCodeUtil.randomCode();
                log.info("Clean_die_thread_before," + task.getTaskId() +
                        "," + task.getAvailable() +
                        "," + DateFormatUtils.format(task.getNextRunTime(),DateFormatUtils.ISO_DATETIME_FORMAT.getPattern()) +
                        "," + TaskThreadPoolFactory.getInstance().isRunningTask(task.getTaskId()) +
                        "," + TaskThreadPoolFactory.getInstance().isAbnormalEndTask(task.getTaskId()) +
                        "," + TaskThreadPoolFactory.getInstance().isSuccessfulEndTask(task.getTaskId(), task.getNextRunTime().getTime()) +
                        "," + sign);

                /**
                 * 状态为"运行",但Task停用(手动停用Task)
                 */
                if (Task.TASK_AVAILABLE.DISABLE.getCode().equals(task.getAvailable())) {
                    log.info("Clean_die_thread_ok," + task.getTaskId() + "," + sign);
                    task.setStatus(Task.TASK_STATUS.END.getCode());
                    taskService.saveTaskRuntime(task);


                    /**
                     * 状态为"运行",但Task异常结束(修改数据库状态失败,异常结束)
                     */
                } else if (TaskThreadPoolFactory.getInstance().isAbnormalEndTask(task.getTaskId())) {
                    log.info("Clean_die_thread_ok," + task.getTaskId() + "," + sign);
                    task.setStatus(Task.TASK_STATUS.END.getCode());
                    taskService.saveTaskRuntime(task);
                    //移除异常结束的Task
                    TaskThreadPoolFactory.getInstance().removeAbnormalEndTask(task.getTaskId());


                    /**
                     * 不在执行队列中 ，也不在成功结束队列中(可能的服务重启)
                     */
                } else if (!TaskThreadPoolFactory.getInstance().isRunningTask(task.getTaskId()) &&
                        !TaskThreadPoolFactory.getInstance().isSuccessfulEndTask(task.getTaskId(), task.getNextRunTime().getTime())) {
                    log.info("Clean_die_thread_ok," + task.getTaskId() + "," + sign);
                    task.setStatus(Task.TASK_STATUS.END.getCode());
                    taskService.saveTaskRuntime(task);
                }
            } catch (Exception e) {
                log.error(e);
            }
        }
    }

    private void resetNextRunTime() {
        Map<String, Object> paramMap = new HashMap<String, Object>();

        paramMap.put("available", Task.TASK_AVAILABLE.ENABLE.getCode());//任务为“启用”
        paramMap.put("status", Task.TASK_STATUS.END.getCode());//运行状态为“结束”

        paramMap.put("_startRow", 1);
        paramMap.put("_endRow", 1000);
        List<Task> taskList = taskService.getTaskList(paramMap);

        for (Task task : taskList) {
            try {
                //重新计算下一次的运行时间
                Date nextRunTime = TaskUtil.calculateNextRunTime(task);

                task.setNextRunTime(nextRunTime);
                task.setStatus(Task.TASK_STATUS.WAIT.getCode());

                taskService.saveTaskRuntime(task);

            } catch (Exception e) {
                log.error(e);
            }
        }
    }

    public TaskService getTaskService() {
        return taskService;
    }

    public void setTaskService(TaskService taskService) {
        this.taskService = taskService;
    }
}
